﻿# importing required modules
import os, time, shutil, subprocess

# from ntpath import join


class folder_dir:
    '类:生产log每日文件夹'

    def __init__(self, new_name: str, root: str, old_path: str, m_time: int):
        self.new_name = new_name
        self.root = root
        self.old_path = old_path
        self.m_time = m_time

    def sweepclean(self, time_limit) -> bool:
        mark = '-cleaned'
        cleaned = False
        print_process = True
        current_time = int(time.time())
        if print_process:
            print(
                "current Time: "
                + time.strftime("%y-%m-%d %H:%M:%S", time.localtime(current_time))
            )
        # C:\AA1 Result\BYD X1F\2023\08\11=>Root path(day)
        # Root/part folder => Part path
        # Part path/file_in_part => file_in_part_path
        for part_folder in os.listdir(self.old_path):
            part_path = os.path.join(self.old_path, part_folder)
            if part_folder[-len(mark) :] == mark or os.path.isfile(part_path):
                continue
            part_time = int(os.stat(part_path).st_mtime)
            if print_process:
                print(part_folder)
                print(time.strftime("%y-%m-%d %H:%M:%S", time.localtime(part_time)))
                print(current_time - part_time)
            if current_time - part_time < time_limit:
                continue
            for file_in_part in os.listdir(part_path):
                file_in_part_path = os.path.join(part_path, file_in_part)
                if file_in_part[:5] == 'Sweep' and (
                    not os.path.isfile(file_in_part_path)
                ):
                    shutil.rmtree(file_in_part_path)
            os.rename(part_path, part_path + mark)
            cleaned = True
        return cleaned


def get_all_folder(result_dir: str) -> list[folder_dir]:
    """列出所有时间符合日期的文件夹，并将其按照时间分类、剪切至临时文件夹

    Args:
        dir (_type_): 扫描文件路径：D:\Gen6 Test Result\BH_assy

    Returns:
        folder_lis(folder_dir[]): 包含文件信息的列表
    """
    folder_lis: list[folder_dir] = []
    # list all producttype folder
    folder_T = os.listdir(result_dir)
    for folder_tt in folder_T:
        root_T = folder_tt
        path_T = os.path.join(result_dir, folder_tt)
        if os.path.isdir(path_T):
            folder_Y = os.listdir(path_T)
            for folder_yy in folder_Y:
                root_Y = root_T + '_' + folder_yy
                path_Y = os.path.join(path_T, folder_yy)
                if os.path.isdir(path_Y):
                    folder_M = os.listdir(path_Y)
                    for folder_mm in folder_M:
                        root_M = root_Y + '_' + folder_mm
                        path_M = os.path.join(path_Y, folder_mm)
                        if os.path.isdir(path_M):
                            folder_D = os.listdir(path_M)
                            for folder_dd in folder_D:
                                root_D = root_M + '_' + folder_dd
                                path_D = os.path.join(path_M, folder_dd)
                                if os.path.isdir(path_D):
                                    new_Path = os.path.join(path_Y, root_D)
                                    stinfo = os.stat(path_D)
                                    f_add = folder_dir(
                                        new_Path, root_D, path_D, int(stinfo.st_mtime)
                                    )
                                    folder_lis.append(f_add)

    return folder_lis


def clean_sweep(folder_List: list[folder_dir], remain_time):
    cleaned = False
    for folder in folder_List:
        if folder.sweepclean(remain_time):
            cleaned = True
    if cleaned:
        print(
            "Deleted some Sweep folder remain for more then %.2f mins"
            % (remain_time / 60)
        )
    else:
        print("No sweep folder to delete")
    return


def sevenzip_1(roots, zipname, filename):
    with py7zr.SevenZipFile(zipname, 'w') as archive:
        archive.writeall(filename, arcname=roots)


def sevenzip_2(path_7za, path_new, path_old):
    cmd = (
        "cmd /c \"\""
        + path_7za
        + "\" a -bsp2 -mmt1 \""
        + path_new
        + "\" \""
        + path_old
        + "\"\""
    )
    os.system(cmd)


def sevenzip_3(path_7za, path_new, path_old):
    cmd = "\"" + path_7za + "\" a \"" + path_new + "\" \"" + path_old + "\"\""
    subprocess.call(cmd)


def sevenzip_4(path_7za, path_new, path_old):
    sw = ' a -bsp2 -mmt2 '
    cmd = "\"" + path_7za + "\"" + sw + "\"" + path_new + "\" \"" + path_old + "\""
    ret = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
    for line in iter(ret.stdout.readline, 'b'):
        line = line.rstrip().decode('utf8')
        print(line)
        if subprocess.Popen.poll(ret) is not None:
            if line == "":
                break
    ret.stdout.close()
    if ret.returncode == 0:
        print(path_old + " zipped!")
    else:
        print(path_old + " zipped with some error")
    return True


def main(sweep_remain, logs_Remain, files_to_archive):
    directory = r'C:\MyTestResults\AA1 Result'
    sevenza_path = (
        r'C:\MyCodeSpace\90.Self Develop\Python\FileAutoZip\7z2201-extra\7za.exe'
    )
    if sweep_remain > logs_Remain and files_to_archive >= 0:
        print("Sweep文件预留时长小于压缩时长，请重新设定")
        return

    # Get the list folder
    day_folder_List: list[folder_dir] = []
    day_folder_List = get_all_folder(directory)
    # Clean Sweep folder
    clean_sweep(day_folder_List, sweep_remain)
    # add a count to limit folder zipped in 1 time to 'files_to_archive'
    count = 0
    for folder in day_folder_List:
        now = int(time.time())
        if (now - folder.m_time) > logs_Remain:
            if count > files_to_archive - 1:
                break
            # name with zip time
            timemark = time.strftime("%y%m%d%H%M%S", time.localtime(int(time.time())))
            newpath = folder.new_name + "-" + timemark + ".7z"
            ### Zip File  ###
            # Methord 1.1
            # sevenzip_1(folder.root,newpath,folder.old_path)

            # Methord 2
            # sevenzip_2(sevenza_path, newpath, folder.old_path)

            # Methord 3
            # sevenzip_3(sevenza_path, newpath, folder.old_path)

            # Methord 4
            success = sevenzip_4(sevenza_path, newpath, folder.old_path)
            if success:
                count += 1
                # delete zipped file
                shutil.rmtree(folder.old_path)
            else:
                print("ziped failed with some issues!")
                return

    if count == 0:
        print("No file ready to zip!")
    else:
        print("All files zipped successfully!")


if __name__ == "__main__":
    main(20, 25, 5)
